﻿using MySql.Data.Entity;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using TaoPortal.DataAccess;
using TaoPortal.Entity;

namespace TaoPortal.DataAccess
{
    [Configuration]
    public class DataContext : DbContext
    {
        public DataContext()
            : base("name=" + GetDBConn())
        {
            //DbConfiguration.SetConfiguration(new MySqlEFConfiguration());
            //Database.SetInitializer<DataContext>(new MigrateDatabaseToLatestVersion<DataContext, SqlServerConfiguration>());
            //Configuration.LazyLoadingEnabled = false;
        }

        public DataContext(string cs)
            : base(cs)
        {
            //Configuration.LazyLoadingEnabled = false;
        }

        public static string GetDBConn()
        {
            return System.Configuration.ConfigurationManager.AppSettings["DBConn"];
        }

        public DbSet<TP_APIUsers> TP_APIUsers { get; set; }
        public DbSet<TP_AppClass> TP_AppClass { get; set; }
        public DbSet<TP_Application> TP_Application { get; set; }
        public DbSet<TP_Article> TP_Article { get; set; }
        public DbSet<TP_ArticleBody> TP_ArticleBody { get; set; }
        public DbSet<TP_ArticleClass> TP_ArticleClass { get; set; }
        public DbSet<TP_ArticleImg> TP_ArticleImg { get; set; }
        public DbSet<TP_ArticleTag> TP_ArticleTag { get; set; }
        public DbSet<TP_Channel> TP_Channel { get; set; }
        public DbSet<TP_ErrorLog> TP_ErrorLog { get; set; }
        public DbSet<TP_Integral> TP_Integral { get; set; }
        public DbSet<TP_Menu> TP_Menu { get; set; }
        public DbSet<TP_Message> TP_Message { get; set; }
        public DbSet<TP_NavBar> TP_NavBar { get; set; }
        public DbSet<TP_Notice> TP_Notice { get; set; }
        public DbSet<TP_ParamValue> TP_ParamValue { get; set; }
        public DbSet<TP_Poll> TP_Poll { get; set; }
        public DbSet<TP_Privilege> TP_Privilege { get; set; }
        public DbSet<TP_ProdImg> TP_ProdImg { get; set; }
        public DbSet<TP_ProdInfo> TP_ProdInfo { get; set; }
        public DbSet<TP_ProdOther> TP_ProdOther { get; set; }
        public DbSet<TP_RestrictAccess> TP_RestrictAccess { get; set; }
        public DbSet<TP_Rights> TP_Rights { get; set; }
        public DbSet<TP_Role> TP_Role { get; set; }
        public DbSet<TP_RoleRights> TP_RoleRights { get; set; }
        public DbSet<TP_SimplePage> TP_SimplePage { get; set; }
        public DbSet<TP_SysAd> TP_SysAd { get; set; }
        public DbSet<TP_SysCfg> TP_SysCfg { get; set; }
        public DbSet<TP_SysFile> TP_SysFile { get; set; }
        public DbSet<TP_SysLog> TP_SysLog { get; set; }
        public DbSet<TP_SysMsg> TP_SysMsg { get; set; }
        public DbSet<TP_Tag> TP_Tag { get; set; }
        public DbSet<TP_Traffic> TP_Traffic { get; set; }
        public DbSet<TP_UserInfo> TP_UserInfo { get; set; }
        public DbSet<TP_UserRoles> TP_UserRoles { get; set; }
        public DbSet<TP_Users> TP_Users { get; set; }
        public DbSet<TP_Zone> TP_Zone { get; set; }

        /// <summary>
        /// 将一个实体设为填加状态
        /// </summary>
        /// <param name="entity">实体</param>
        public void AddEntity<T>(T entity) where T : BasePoco
        {
            this.Entry(entity).State = EntityState.Added;
        }

        /// <summary>
        /// 将一个实体设为修改状态
        /// </summary>
        /// <param name="entity">实体</param>
        public void UpdateEntity<T>(T entity) where T : BasePoco
        {
            this.Entry(entity).State = EntityState.Modified;
        }

        /// <summary>
        /// 将一个实体的某个字段设为修改状态，用于只更新个别字段的情况
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="entity">实体</param>
        /// <param name="fieldExp">要设定为修改状态的字段</param>
        public void UpdateProperty<T>(T entity, Expression<Func<T, object>> fieldExp)
            where T : BasePoco
        {
            var set = this.Set<T>();
            if (set.Local.Where(x => x.ID == entity.ID).FirstOrDefault() == null)
            {
                set.Attach(entity);
            }
            this.Entry(entity).Property(fieldExp).IsModified = true;
        }
        /// <summary>
        /// 将一个实体的某个字段设为修改状态，用于只更新个别字段的情况
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="entity">实体</param>
        /// <param name="fieldName">要设定为修改状态的字段</param>
        public void UpdateProperty<T>(T entity, string fieldName)
            where T : BasePoco
        {
            var set = this.Set<T>();
            if (set.Local.Where(x => x.ID == entity.ID).FirstOrDefault() == null)
            {
                set.Attach(entity);
            }
            this.Entry(entity).Property(fieldName).IsModified = true;
        }
        /// <summary>
        /// 将一个实体设定为删除状态
        /// </summary>
        /// <param name="entity">实体</param>
        public void DeleteEntity<T>(T entity) where T : BasePoco
        {
            var set = this.Set<T>();
            if (set.Local.Where(x => x.ID == entity.ID).FirstOrDefault() == null)
            {
                set.Attach(entity);
            }
            set.Remove(entity);
        }

        public void DisableChangeDetection()
        {
            this.Configuration.AutoDetectChangesEnabled = false;
        }

        public void EnableChangeDetection()
        {
            this.Configuration.AutoDetectChangesEnabled = true;
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //Database.SetInitializer<DataContext>(null);
            //移除EF默认的一对多级联删除设定
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        }
    }
}
